precision mediump float; // 中精度浮点数

uniform float times;
varying vec2 vUV;
varying vec3 vPosition;
varying vec2 vResolution;
uniform sampler2D u_texture;

// ========= Noise ===========

#define MOD3 vec3(.1031, .11369, .13787)
//#define MOD3 vec3(443.8975,397.2973, 491.1871)
float hash31( vec3 p3 ){
    p3 = fract( p3 * MOD3 );
    p3 += dot( p3 , p3.yzx + 19.19 );
    return - 1.0 + 2.0 * fract( ( p3.x + p3.y ) * p3.z );
}

vec3 hash33( vec3 p3 ){
    p3 = fract( p3 * MOD3 );
    p3 += dot( p3 , p3.yxz + 19.19 );
    return - 1.0 + 2.0 * fract( vec3( ( p3.x + p3.y ) * p3.z , ( p3.x + p3.z ) * p3.y , ( p3.y + p3.z ) * p3.x ) );
}

float value_noise( vec3 p ){
    vec3 pi = floor( p );
    vec3 pf = p - pi;

    vec3 w = pf * pf * ( 3.0 - 2.0 * pf );

    return mix( mix( mix( hash31( pi + vec3( 0 , 0 , 0 ) ) , hash31( pi + vec3( 1 , 0 , 0 ) ) , w.x ) , mix( hash31( pi + vec3( 0 , 0 , 1 ) ) , hash31( pi + vec3( 1 , 0 , 1 ) ) , w.x ) , w.z ) , mix( mix( hash31( pi + vec3( 0 , 1 , 0 ) ) , hash31( pi + vec3( 1 , 1 , 0 ) ) , w.x ) , mix( hash31( pi + vec3( 0 , 1 , 1 ) ) , hash31( pi + vec3( 1 , 1 , 1 ) ) , w.x ) , w.z ) , w.y );
}

float perlin_noise( vec3 p ){
    vec3 pi = floor( p );
    vec3 pf = p - pi;

    vec3 w = pf * pf * ( 3.0 - 2.0 * pf );

    // return mix( mix( mix( dot( pf - vec3( 0 , 0 , 0 ) , hash33( pi + vec3( 0 , 0 , 0 ) ) ) , dot( pf - vec3( 1 , 0 , 0 ) , hash33( pi + vec3( 1 , 0 , 0 ) ) ) , w.x ) , mix( dot( pf - vec3( 0 , 0 , 1 ) , hash33( pi + vec3( 0 , 0 , 1 ) ) ) , dot( pf - vec3( 1 , 0 , 1 ) , hash33( pi + vec3( 1 , 0 , 1 ) ) ) , w.x ) , w.z ) , mix( mix( dot( pf - vec3( 0 , 1 , 0 ) , hash33( pi + vec3( 0 , 1 , 0 ) ) ) , dot( pf - vec3( 1 , 1 , 0 ) , hash33( pi + vec3( 1 , 1 , 0 ) ) ) , w.x ) , mix( dot( pf - vec3( 0 , 1 , 1 ) , hash33( pi + vec3( 0 , 1 , 1 ) ) ) , dot( pf - vec3( 1 , 1 , 1 ) , hash33( pi + vec3( 1 , 1 , 1 ) ) ) , w.x ) , w.z ) , w.y );
    float vals = mix( mix( mix( dot( pf - vec3( 0 , 0 , 0 ) , hash33( pi + vec3( 0 , 0 , 0 ) ) ) , dot( pf - vec3( 1 , 0 , 0 ) , hash33( pi + vec3( 1 , 0 , 0 ) ) ) , w.x ) , mix( dot( pf - vec3( 0 , 0 , 1 ) , hash33( pi + vec3( 0 , 0 , 1 ) ) ) , dot( pf - vec3( 1 , 0 , 1 ) , hash33( pi + vec3( 1 , 0 , 1 ) ) ) , w.x ) , w.z ) , mix( mix( dot( pf - vec3( 0 , 1 , 0 ) , hash33( pi + vec3( 0 , 1 , 0 ) ) ) , dot( pf - vec3( 1 , 1 , 0 ) , hash33( pi + vec3( 1 , 1 , 0 ) ) ) , w.x ) , mix( dot( pf - vec3( 0 , 1 , 1 ) , hash33( pi + vec3( 0 , 1 , 1 ) ) ) , dot( pf - vec3( 1 , 1 , 1 ) , hash33( pi + vec3( 1 , 1 , 1 ) ) ) , w.x ) , w.z ) , w.y );
    return ( vals * 4. );
    // return vals;
}

vec3 colorDepthNormal( vec3 cuv ){
    float depthValue = perlin_noise( cuv + vec3( times ) );
    float offset = 0.3;

    float depthLeft = perlin_noise( cuv + vec3( offset , 0. , 0. ) + vec3( times ) );
    float depthRight = perlin_noise( cuv + vec3( - offset , 0. , 0. ) + vec3( times ) );
    float depthUp = perlin_noise( cuv + vec3( 0. , 0. , offset ) + vec3( times ) );
    float depthDown = perlin_noise( cuv + vec3( 0. , 0. , - offset ) + vec3( times ) );

      // 计算视图空间法线（使用中心差分法）
    vec3 normalView;
    normalView.x = ( depthLeft - depthRight ) * 0.5;
    normalView.y = ( depthDown - depthUp ) * 0.5;
    normalView.z = 1.0;

    // 将视图空间法线转换为世界空间
    mat4 viewInverseTransposeMatrix = mat4( 1.0 ); // 在这里设置您的视图矩阵的逆转置矩阵
    vec3 normalWorld = ( viewInverseTransposeMatrix * vec4( normalView , 0.0 ) ).xyz;
    // 将法线向量映射到 [0, 1] 范围，并将其表示为彩色像素
    // return normalize( normalWorld ) * 0.5 + 0.5;

    return vec3( normalView );
}

void main( ){

    vec3 screenUV = vec3( vUV.x , 0. , vUV.y ) * 10.;
    vec3 depthPos = vec3( perlin_noise( screenUV + vec3( times ) ) );
    depthPos *= 0.7;
    depthPos += vec3( 0.3 );

    vec3 outPutColor = vec3( 0.2 , 0.2 , 0.29 );
    // outPutColor *= depthPos.r;

//定义一个灯光的方向
    vec3 colorDir = vec3( 0.4 , -0.69 , 0.69 );
    vec3 lightColor = vec3( 0.4 , 0.69 , 0.69 );

//计算法线贴图转换
    vec3 normalColor = colorDepthNormal( screenUV );

//计算灯光与法线的点乘
    float angleValue = dot( colorDir , normalColor );
    if ( angleValue > 0. ){
        outPutColor += ( angleValue * lightColor * depthPos.r );
    }

    // normalColor += normalColor;

    gl_FragColor = vec4( vec3( outPutColor ) , 1.0 );
}